package com.hzlj.position.config.dao;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fz.common.base.converter.QueryWrapperConverterPlus;
import com.fz.common.base.converter.RemoveWrapperPlus;
import com.fz.common.base.dto.DeleteCommonDTO;
import com.fz.common.base.dto.PageParamDTO;
import com.fz.common.base.dto.QueryPageResultDTO;
import com.fz.common.base.env.Env;
import com.github.yulichang.wrapper.MPJAbstractLambdaWrapper;
import com.github.yulichang.wrapper.interfaces.WrapperFunction;
import com.hzlj.position.config.common.dto.jzJbxxDeviceBind.JzJbxxDeviceBindQueryResultDTO;
import com.hzlj.position.config.common.dto.jzJbxxDeviceBind.JzJbxxDeviceBindSimpleQueryParamDTO;
import com.hzlj.position.config.common.dto.jzJbxxDeviceBind.JzJbxxDeviceBindWithLocateTimesDTO;
import com.hzlj.position.config.common.model.JzJbxxConfig;
import com.hzlj.position.config.common.model.JzJbxxDeviceBind;
import com.hzlj.position.config.mapper.JzJbxxDeviceBindMapper;
import com.hzlj.sqjz.jz.common.constant.JzJoin;
import com.hzlj.sqjz.jz.common.enums.Jzyclb;
import com.hzlj.sqjz.jz.common.model.JzJbxx;
import com.hzlj.sqjz.jz.common.model.JzYc;
import com.hzlj.sqjz.lc.common.model.LcMkh;
import org.springframework.stereotype.Repository;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

import static com.hzlj.sqjz.config.common.constant.Constant.JZZT_ZJ_ENV;

/**
 * 设备绑定表(JzJbxxDeviceBind)表操作类
 *
 * @author lifh
 * @date 2023-03-13 16:57:41
 */
@Repository
public class JzJbxxDeviceBindDao extends ServiceImpl<JzJbxxDeviceBindMapper, JzJbxxDeviceBind> {
    @Resource
    private JzJbxxDeviceBindMapper jzJbxxDeviceBindMapper;

    public JzJbxxDeviceBind getJzJbxxDeviceBindByJzId(String jzId, String channel) {
        LambdaQueryWrapper<JzJbxxDeviceBind> queryWrapper = new QueryWrapper<JzJbxxDeviceBind>().lambda()
                .eq(JzJbxxDeviceBind::getJzId, jzId)
                .eq(JzJbxxDeviceBind::getChannel, channel);
        return this.getOne(queryWrapper);
    }

    public JzJbxxDeviceBind getJzJbxxDeviceBindByDeviceCode(String deviceCode, String channel) {
        LambdaQueryWrapper<JzJbxxDeviceBind> queryWrapper = new QueryWrapper<JzJbxxDeviceBind>().lambda()
                .eq(JzJbxxDeviceBind::getDeviceCode, deviceCode)
                .eq(JzJbxxDeviceBind::getChannel, channel);
        return this.getOne(queryWrapper);
    }

    /**
     * 修改数据
     *
     * @param dto 实例对象
     * @return 实例对象
     */
    public boolean updateJzJbxxDeviceBind(JzJbxxDeviceBind dto) {
        LambdaQueryWrapper<JzJbxxDeviceBind> queryWrapper = new QueryWrapper<JzJbxxDeviceBind>().lambda()
                .eq(JzJbxxDeviceBind::getId, dto.getId());
        return this.update(dto, queryWrapper);
    }

    /**
     * 删除数据
     */
    public boolean deleteJzJbxxDeviceBind(DeleteCommonDTO<String> dto) {
        return RemoveWrapperPlus.remove(this, dto);
    }


    public boolean exists(String jzId, String channelType) {
        String id = QueryWrapperConverterPlus.of(jzJbxxDeviceBindMapper)
                .selectOneField(String.class, q -> q
                        .selectMin(JzJbxxDeviceBind::getId)
                        .eq(JzJbxxDeviceBind::getJzId, jzId)
                        .eq(JzJbxxDeviceBind::getChannelType, channelType)
                );
        return id != null;
    }

    public List<String> listJzIds(JzJbxxDeviceBindSimpleQueryParamDTO dto) {
        return queryWrapper(dto)
                .list(JzJbxx::getId, dto, null);
    }

    public List<JzJbxxDeviceBindWithLocateTimesDTO> listJzJbxxDeviceBind4LocateTimes(JzJbxxDeviceBindSimpleQueryParamDTO dto) {
        return queryWrapper(dto)
                .list(JzJbxxDeviceBindWithLocateTimesDTO.class, dto);
    }

    public List<JzJbxxDeviceBindQueryResultDTO> listJzJbxxDeviceBind(JzJbxxDeviceBindSimpleQueryParamDTO dto) {
        return queryWrapper(dto)
                .list(JzJbxxDeviceBindQueryResultDTO.class, dto);
    }


    public QueryPageResultDTO<JzJbxxDeviceBindQueryResultDTO> pageJzJbxxDeviceBind(JzJbxxDeviceBindSimpleQueryParamDTO dto, PageParamDTO page) {
        return queryWrapper(dto)
                .leftJoin(JzJbxxConfig.class, on -> on.eq(JzJbxxConfig::getId, JzJbxxDeviceBind::getJzId).eq(JzJbxxConfig::getValid, true))
                .page(JzJbxxDeviceBindQueryResultDTO.class, dto, page);
    }

    public List<String> ids4NeedDel() {
        return QueryWrapperConverterPlus.of(jzJbxxDeviceBindMapper)
                .notExists(JzJbxx.class, on -> on
                        .eq(JzJbxxDeviceBind::getJzId, JzJbxx::getId)
                        .eq(JzJbxx::getValid, true)
                        .eq(JzJbxx::getJzzt, Env.getProperty(JZZT_ZJ_ENV))
                )
                .list(JzJbxxDeviceBind::getId, null, null);
    }

    private QueryWrapperConverterPlus<JzJbxxDeviceBind> queryWrapper(JzJbxxDeviceBindSimpleQueryParamDTO params) {
        DateTime belongDay = DateUtil.beginOfDay(new Date());
        return QueryWrapperConverterPlus.of(jzJbxxDeviceBindMapper)
                .innerJoin(JzJbxx.class, JzJoin.zj(JzJbxxDeviceBind::getJzId))
                .exists(Boolean.TRUE.equals(params.getMkh()), LcMkh.class, mhk(belongDay))
                .notExists(Boolean.FALSE.equals(params.getMkh()), LcMkh.class, mhk(belongDay))
                .exists(Boolean.TRUE.equals(params.getMdy()), JzJbxxConfig.class, mdy())
                .notExists(Boolean.FALSE.equals(params.getMdy()), JzJbxxConfig.class, mdy())
                .exists(Boolean.TRUE.equals(params.getQzcs()), JzYc.class, qzcs(belongDay))
                .notExists(Boolean.FALSE.equals(params.getQzcs()), JzYc.class, qzcs(belongDay))
                ;
    }

    private WrapperFunction<MPJAbstractLambdaWrapper<LcMkh, ?>> mhk(Date belongDay) {
        return on -> on
                .eq(LcMkh::getJzId, JzJbxxDeviceBind::getJzId)
                .le(LcMkh::getKsrq, belongDay)
                .ge(LcMkh::getJsrq, belongDay);
    }

    private WrapperFunction<MPJAbstractLambdaWrapper<JzJbxxConfig, ?>> mdy() {
        return on -> on
                .eq(JzJbxxConfig::getId, JzJbxxDeviceBind::getJzId)
                .eq(JzJbxxConfig::getMdy, true);
    }

    private WrapperFunction<MPJAbstractLambdaWrapper<JzYc, ?>> qzcs(Date belongDay) {
        return on -> on
                .eq(JzYc::getJzId, JzJbxxDeviceBind::getJzId)
                .eq(JzYc::getYclb, Jzyclb.QZCS.getCode())
                .le(JzYc::getKsrq, belongDay)
                .and(on1 -> on1
                        .ge("jz_yc_.jsrq", belongDay)
                        .or()
                        .isNull("jz_yc_.jsrq")
                );
    }

}

